﻿using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Server;
using Newtonsoft.Json.Linq;
using System.Text;
using util_c_sharp.util.mqtt;
using wsacq.com.util;

namespace util_c_sharp.util
{
    internal class UtilMqtt
    {
        static IManagedMqttClient mqttClientManaged = new MqttFactory().CreateManagedMqttClient();
        
        /// <summary>
        /// 初始化mqtt链接
        /// </summary>
        /// <param name="handler">消息通知调用函数</param>
        internal static async void InitMqttClient(Action<MqttApplicationMessageReceivedEventArgs> handler)
        {
            try
            {
                mqttClientManaged.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
                mqttClientManaged.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
                mqttClientManaged.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(handler ?? OnSubscriberMessageReceived);

                await mqttClientManaged.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("demo_cmd").Build());

                new Thread(() =>
                {
                    mqttClientManaged.StartAsync(InitOptionsOfNtd());
                    Console.WriteLine("mqtt client 启动成功！");
                    UtilWait.Wait();
                }).Start();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            
        }

        private static ManagedMqttClientOptions InitOptionsOfNtd()
        {
            return new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
                .WithClientOptions(FactoryMqttOption.InitOptionsOfNtd())
                .Build();
        }

        private static ManagedMqttClientOptions InitOptionsOfFm()
        {
            return new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
                .WithClientOptions(FactoryMqttOption.InitOptionsOfFm())
                .Build();
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="topic">消息主题</param>
        /// <param name="payload">消息内容</param>
        internal static async void PubMsg(string topic, string payload)
        {
            if (mqttClientManaged == null)
            {
                return;
            }
            var message = new MqttApplicationMessageBuilder()
                .WithTopic(topic)
                .WithPayload(payload)
                .WithExactlyOnceQoS()
                .WithRetainFlag()
                .Build();

            await mqttClientManaged.PublishAsync(message, CancellationToken.None);
        }

        private static void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            Console.WriteLine("消息通知");
            Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
            Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
            Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
            Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");
            Console.WriteLine();
        }
        private static void OnSubscriberConnected(MqttClientConnectedEventArgs args)
        {
            JObject jObject = JObject.FromObject(args);
            UtilLog.Log("mqtt 链接成功 - " + jObject.ToString());
        }

        private static void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs args)
        {
            JObject jObject = JObject.FromObject(args);
            UtilLog.Log("mqtt 链接断开 - " + jObject.ToString());
        }
    }

}
